#!/bin/bash
#
# Copyright 2015-2017 Adrian DC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# === GitHub Url Cherry-Pick ===
function gitcpu()
{
  # Usage
  if [ -z "${1}" ]; then
    echo '';
    echo ' Usage: gitcpu <githuburltocommit> [branch] (Git URL commit cherry-picker)';
    echo '';
    return;
  fi;

  # Variables
  local link=${1};
  local branch=${2:-lineage-15.0};
  local project;
  local commit;

  # Input handling
  project=$(echo "${link}" \
          | sed 's/.*\(github.com\/.*\)\/commit\/.*/http:\/\/\1/');
  commit=$(echo "${link}" \
         | sed 's/.*\/commit\/\(.*\)/\1/');

  # Input verification
  if [ -z "${project}" ] || [ -z "${commit}" ]; then
    echo '';
    echo " Error: Not a GitHub commit url '${link}'";
    echo '';
    return;
  fi;

  # Fetch and pick
  git fetch "${project}" "${branch}";
  echo '';
  git show -M --oneline --stat "${commit}";
  echo '';
  git cherry-pick "${commit}";
}

# === Git Merger ===
function gitmerges()
{
  # Usage
  if [ -z "${1}" ]; then
    echo '';
    echo ' Usage: gitmerges <commit_sha1> [count] (Attempt to merge commit history)';
    echo '';
    return;
  fi;

  # Variables
  cnt=${2:-30};

  # Introduction
  echo '';
  echo -e " \e[1;37mSearching mergeable commits in ${1} tree...\e[0m";
  echo '';

  # Search commits
  git rev-list "${1}" --reverse --pretty=oneline -- . \
    | tail -n "${cnt}" \
    | while read -r line;
  do
    sha1=$(echo "${line}" | cut -c -40);
    title=$(echo "${line}" | cut -c 42-);
    if ! git rev-list HEAD --pretty=oneline -- . | grep -iq "${title}"; then
      echo -e " \e[1;31m${sha1} : \e[1;37m${title}\e[0m";
      git cherry-pick "${sha1}";
      git reset --hard HEAD;
      echo '';
    fi;
  done;
}

# === GitHub Origin Cherry-Pick ===
function gitcpo()
{
  # Usage
  echo '';
  if [ -z "${1}" ] || [ -z "${2}" ]; then
    echo -e '  \e[1;37mGit Origin Cherry-Pick.\e[0m';
    echo '    Usage: gitcpo <branch> <amount_of_commits> (GitHub origin cherry-picker)';
    echo '';
    return;
  fi;

  # Variables
  local gitremote=origin;

  # Cherry-Pick
  git cherry-pick --abort > /dev/null 2>&1;
  if git fetch "${gitremote}" "${1}" && [ "${2}" -gt 0 ]; then
    git cherry-pick FETCH_HEAD~$((${2} - 1))^..FETCH_HEAD;
  fi;
}


# === GitHub Url Cherry-pick ===
function gitcpup()
{
  # Usage: gitcpup [url] (Git URL patch applier)';

  # Variables
  local tmpfile;
  local tmpurl=${1};
  echo '';

  # Finish previous one
  if [ -z "${tmpurl}" ]; then
    git am --continue;
    return;
  fi;

  # Remote additional informations
  tmpurl=${tmpurl%%#*};

  # GitHub/GitLab patch
  if [[ ! "${tmpurl}" == *'.patch'* ]]; then
    if [[ "${tmpurl}" == *'github.com'* ]] || [[ "${tmpurl}" == *'gitlab.com'* ]] ||
       [[ "${tmpurl}" == *'git.bricked.de'* ]]; then
      tmpurl=${tmpurl}.patch;
    fi;
  fi;

  # CodeAurora patch
  if [[ "${tmpurl}" == *'codeaurora.org'* ]]; then
    if [[ ! "${tmpurl}" == *'patch/'* ]]; then
      tmpurl=${tmpurl/commit\/?*id=/patch\/?id=};
    fi;
    if [[ ! "${tmpurl}" == *'patch/'* ]]; then
      echo '';
      echo -e ' \e[1;33mgitcpup: Link incomplete, add "..." around the url\e[0m';
      echo " Failed on ${tmpurl}";
      echo '';
      return;
    fi;
  fi;

  # Git Kernel patch
  if [[ "${tmpurl}" == *'kernel.org'* ]]; then
    if [[ ! "${tmpurl}" == *'patch/'* ]]; then
      tmpurl=${tmpurl/commit\/?*id=/patch\/?id=};
    fi;
    if [[ ! "${tmpurl}" == *'patch/'* ]]; then
      echo '';
      echo -e ' \e[1;33mgitcpup: Link incomplete, add "..." around the url\e[0m';
      echo " Failed on ${tmpurl}";
      echo '';
      return;
    fi;
  fi;

  # Download patch
  tmpfile=$(mktemp);
  rm -rf .git/rebase-apply;
  curl "${tmpurl}" > "${tmpfile}" 2> /dev/null;

  # Files renaming
  if [ ! -z "${2}" ] && [ ! -z "${3}" ]; then
    sed -i "s#${2}#${3}#g" "${tmpfile}";
  fi;

  # Cherry-pick
  if ! git am -3 "${tmpfile}"; then
    echo '';
    echo " Failed on ${tmpurl}";
    echo '';
    return;
  fi;
  git log --max-count=1 --pretty=oneline;
  echo '';

  # End of process
  rm -f "${tmpfile}";
}

# === GitHub Url Cherry-pick Renamed ===
function gitcpur()
{
  # Usage
  if [ -z "${3}" ]; then
    echo '';
    echo ' Usage: gitcpur <url> <search_text> <replace_text> (Git URL retargeted patch applier)';
    echo '';
    return;
  fi;

  # Variables
  local tmpurl=${1};
  local search=${2//\//\\\/};
  local replace=${3//\//\\\/};
  local tmpfile;
  echo '';

  # Remote additional informations
  tmpurl=${tmpurl%%#*};

  # GitHub/GitLab patch
  if [[ ! "${tmpurl}" == *'.patch'* ]]; then
    if [[ "${tmpurl}" == *'github.com'* ]] || [[ "${tmpurl}" == *'gitlab.com'* ]] ||
       [[ "${tmpurl}" == *'git.bricked.de'* ]]; then
      tmpurl=${tmpurl}.patch;
    fi;
  fi;

  # Cherry-pick
  tmpfile=$(mktemp);
  rm -rf .git/rebase-apply;
  curl "${tmpurl}" | sed "s/${search}/${replace}/g" > "${tmpfile}" 2> /dev/null;
  if ! git am -3 "${tmpfile}"; then
    echo '';
    echo " Failed on ${tmpurl}";
    echo '';
    return;
  fi;
  git log --max-count=1 --pretty=oneline;
  echo '';

  # End of process
  rm -f "${tmpfile}";
}

# === GitHub Url Cherry-pick Helpers ===
function gitcpupprima() { gitcpup "${1}" CORE drivers/staging/prima/CORE; }
